package com.webridge.wpmtest.util;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.json.JSONArray;
import org.json.JSONObject;

import com.ptc.core.components.rendering.guicomponents.SuggestTextBox;
import com.ptc.core.lwc.common.view.TypeDefinitionReadView;
import com.ptc.core.lwc.server.TypeDefinitionServiceHelper;
import com.ptc.core.meta.common.TypeIdentifier;
import com.ptc.core.meta.type.mgmt.server.TypeDefinition;
import com.ptc.windchill.enterprise.object.util.TypeHelper;

import wt.access.AccessControlHelper;
import wt.access.AccessControlRule;
import wt.access.NotAuthorizedException;
import wt.admin.AdminDomainRef;
import wt.admin.AdministrativeDomain;
import wt.admin.AdministrativeDomainHelper;
import wt.doc.WTDocument;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.folder.Folder;
import wt.folder.FolderHelper;
import wt.folder.SubFolder;
import wt.inf.container.WTContainerException;
import wt.inf.team.ContainerTeam;
import wt.inf.team.ContainerTeamHelper;
import wt.lifecycle.State;
import wt.log4j.LogR;
import wt.method.RemoteAccess;
import wt.method.RemoteMethodServer;
import wt.org.WTPrincipal;
import wt.org.WTPrincipalReference;
import wt.org.WTUser;
import wt.pdmlink.PDMLinkProduct;
import wt.project.Role;
import wt.query.ClassAttribute;
import wt.query.OrderBy;
import wt.query.OrderByExpression;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.team.Team;
import wt.team.TeamHelper;
import wt.util.WTException;
import wt.vc.config.ConfigException;
import wt.workflow.engine.WfEngineHelper;
import wt.workflow.engine.WfProcess;
import wt.workflow.engine.WfState;

public class ContainerUtil implements RemoteAccess{
    public static final String ACCESS_CONTROL_PARENT_TYPE = "wt.doc.WTDocument-wt.epm.EPMDocument-wt.part.WTPart-wt.change2.WTChangeOrder2-wt.change2.WTChangeActivity2-wt.change2.WTChangeRequest2"; 
    private final static Logger LOGGER = LogR
            .getLogger(ContainerUtil.class.getName());
    /**
     * 获取PDMLink的产品库，JSON格式
     * @return JSON String
     */
    @SuppressWarnings("deprecation")
    public static String getAllProducts() {
        String prodStr = "";
        List<String> list = new ArrayList<String>();
        
        JSONArray array = new JSONArray();
        List<Map<String,String>>listJSON = new ArrayList<Map<String,String>>();
        try {
            PDMLinkProduct product = null;
            QuerySpec qus = new QuerySpec(PDMLinkProduct.class);
            
            ClassAttribute clsAttr = new ClassAttribute(PDMLinkProduct.class, PDMLinkProduct.MODIFY_TIMESTAMP);
            OrderBy order = new OrderBy((OrderByExpression) clsAttr, true);
            qus.appendOrderBy(order);
            QueryResult qur = PersistenceHelper.manager.find(qus);
            int index=1;
            
           while(qur.hasMoreElements()) {
               Map<String,String>map = new HashMap<String,String>();
                product = (PDMLinkProduct) qur.nextElement();
                String productName = product.getName();
                list.add(productName);
//                map.put(productName, String.valueOf(index));
                map.put("name", productName);
                map.put("value", String.valueOf(index));
                listJSON.add(map);
                LOGGER.debug("MAP:" + map);
                array.put(map);
                index++;
            }
        } catch (WTException e) {
            e.printStackTrace();
        }
//        prodStr = JSON.toJSONString(array);
        prodStr = array.toJSONString();
        
//        LOGGER.debug("prodStr1:" + prodStr);
//        prodStr = prodStr.replaceAll("\"", "'");
//        LOGGER.debug("prodStr2:" + prodStr);
//        
//        
//        prodStr = toJson(listJSON);
        LOGGER.debug("prodStr3:" + prodStr);
        JSONObject json = new JSONObject();
        return prodStr;
    }
    public static String toJson(Object obj) {
        ObjectMapper mapper = new ObjectMapper();
        SerializationConfig cfg = mapper.getSerializationConfig();
        cfg = cfg.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
        mapper.setSerializationConfig(cfg);
        try {
            String json = mapper.writeValueAsString(obj);
            return json;
        }
        catch (IOException e) {
            return "";
        }
    }
    
    /**
     * 依据产品Name查询Product
     * @param productName
     * @return PDMLinkProduct
     */
    @SuppressWarnings("deprecation")
    public static PDMLinkProduct getProductByName(String productName) {
        PDMLinkProduct product = null;
        try {

            QuerySpec qus = new QuerySpec(PDMLinkProduct.class);
            SearchCondition sec = new SearchCondition(PDMLinkProduct.class, PDMLinkProduct.NAME, SearchCondition.EQUAL,
                    productName, false);
            qus.appendSearchCondition(sec);
            ClassAttribute clsAttr = new ClassAttribute(PDMLinkProduct.class, PDMLinkProduct.MODIFY_TIMESTAMP);
            OrderBy order = new OrderBy((OrderByExpression) clsAttr, true);
            qus.appendOrderBy(order);
            QueryResult qur = PersistenceHelper.manager.find(qus);
            if (qur.hasMoreElements()) {
                product = (PDMLinkProduct) qur.nextElement();

            }
        } catch (WTException e) {
            e.printStackTrace();
        }

        return product;
    }
    
    
 /**
  * 获取产品库下的域。
  * @param productName
  * @return
  * @throws WTException
  */
    public static String getProductDomain(String productName) throws WTException{
        org.json.JSONArray jsonArray =  new JSONArray();
        Map<String, String>map = new HashMap<String, String>();
        
        PDMLinkProduct product = getProductByName(productName);
        if(product == null)
            return "";
        String orgName = product.getOrganizationName();
        String containerPath = "[/wt.inf.container.OrgContainer=" + orgName + "/wt.pdmlink.PDMLinkProduct=" + product.getName() +"]" ;
        LOGGER.debug("containerPath:" + containerPath);
         AdministrativeDomain sourceDomain = AdministrativeDomainHelper.manager.getDomain(containerPath + "/Default");
        
        ArrayList childDomains = AdministrativeDomainHelper.manager.getChildDomains(AdminDomainRef.newAdminDomainRef(sourceDomain));
       
        LOGGER.debug("childDomains SIZE:" + childDomains.size());
        Iterator it = childDomains.iterator();
        while(it.hasNext()){
            AdminDomainRef dRef = (AdminDomainRef) it.next();
            AdministrativeDomain childDomain = (AdministrativeDomain) dRef.getObject();
            LOGGER.debug("child domain name:" + childDomain.getName());
            LOGGER.debug("child domain desc:" + childDomain.getDescription());
            LOGGER.debug("childDomain.getContainerName():" + childDomain.getContainerName());
            String path = AdministrativeDomainHelper.manager.getDomainPath(childDomain);
            map.put("name", childDomain.getName());
            map.put("path", path);
            jsonArray.put(map);
            
        } 
        //Collection<AccessControlRule> aclList = AccessControlHelper.manager.getAccessControlRules(AdminDomainRef.newAdminDomainRef(sourceDomain));
        LOGGER.debug("JSON Array:" + jsonArray.toJSONString());
        return jsonArray.toJSONString();
        
        
        
    }
    
    
    /**
     * 
     * @param productName
     * @return 
     */
    public static String getProductTeam(String productName){
        String teamStr = "";
        org.json.JSONArray jsonArray =  new JSONArray();
        Map<String, String>map = new HashMap<String, String>();
        PDMLinkProduct product = getProductByName(productName);
        if(product == null)
            return "";
        try {
            ContainerTeam team = ContainerTeamHelper.service.getContainerTeam(product);
            Map teamMap = team.getAllMembers();
            Vector vector = team.getRoles();
            Iterator it = vector.iterator();
            while(it.hasNext()){
                Role role = ( Role) it.next();
                String internalName = role.getStringValue().substring(16);
                LOGGER.debug("StringValue:" + role.getStringValue().substring(16));
                String displayName = role.getDisplay(Locale.CHINA);
                LOGGER.debug("Role Name:" + role.getDisplay());
                map.put("value", internalName);
                map.put("name", displayName);
                jsonArray.put(map);
            }
            
            
        } catch (WTException e) {
            e.printStackTrace();
        }        
        teamStr = jsonArray.toJSONString();
        LOGGER.debug("Team Role JSON:" + teamStr);
        return teamStr;
        
    }
    
    /**
     * Get Windchill Type。
     * @throws WTException 
     * @throws WTContainerException 
     * @throws NotAuthorizedException 
     *     AccessControlSurrogate, EPMDocument, 
     *     EPMDocumentMaster, EPMMemberLink, EPMReferenceLink, 
     *     FederatedLink, PDMLinkProduct, Project2, PromotionNotice, 
     *     WTAnalysisActivity, WTChangeActivity2, WTChangeInvestigation, 
     *     WTChangeIssue, WTChangeOrder2, WTChangeProposal, 
     *     WTChangeRequest2, WTDocument, WTLibrary, WTPart, 
     *     WTPartUsageLink, WTProductInstance2
     * 
     * 
     */
    public static String getWindchillType() throws NotAuthorizedException, WTContainerException, WTException{
        String typeStr = "";
        String[] allTypes = ACCESS_CONTROL_PARENT_TYPE.split("-");
        Map map = new HashMap();
        JSONArray json = new JSONArray();
        LOGGER.debug("allTypes:" + allTypes.length);
        for(int i=0;i<allTypes.length;i++){
            String type = allTypes[i];
            LOGGER.debug("type:" + type);
            TypeDefinitionReadView newParentReadView = TypeDefinitionServiceHelper.service.getTypeDefView(type);
            getChildType(newParentReadView, map, json);
        }
        LOGGER.debug("JSON Array:" + json.toJSONString());
        return typeStr;
    }
    /**
     * 迭代寻找各级子类
     * @param ptdrv
     * @param map
     * @param json
     * @throws NotAuthorizedException
     * @throws WTContainerException
     * @throws WTException
     */
    public static void getChildType(TypeDefinitionReadView ptdrv, Map map,JSONArray json) throws NotAuthorizedException, WTContainerException, WTException{
        map.put("internalName", ptdrv.getTypeIdentifier().getTypename());
        map.put("displayName", ptdrv.getDisplayName());
        json.put(map);
        LOGGER.debug(" map:" + map);
        Set<TypeDefinitionReadView>set = TypeDefinitionServiceHelper.service.getChildTypeDefViews(ptdrv);
        Iterator it = set.iterator();
        if(set.size()>0)
            for(TypeDefinitionReadView tdrv:set){
                map.put("internalName", tdrv.getTypeIdentifier().getTypename());
                map.put("displayName", tdrv.getDisplayName());
                json.put(map);
                LOGGER.debug(" map:" + map);
                getChildType(tdrv,map,json);
                
            }
    }
    
    /**
     * 获取系统所有生命周期状态
     * @return
     */
    public static String getAllState() {
        String stateStr = "";
        Map map = new HashMap();
        JSONArray json = new JSONArray();
        State[] states = State.getStateSet();
        for (int i = 0; i < states.length; i++) {
            State state = states[i];
            map.put("internalName", state.getStringValue().substring(19));
            map.put("displayName", state.getDisplay(Locale.CHINA));
            json.put(map);
        }
        LOGGER.debug("STATE JSON:" + json.toJSONString());
        return stateStr;

    }
    /**
     * 获得团队中的角色中参与者的枚举
     */
    public static Enumeration getRoleEnumeration(Team team, String rolename)
            throws WTException {
        if (rolename == null || rolename.length() == 0) {
            return null;
        }
        Role role = (Role) (Role.toRole(rolename));
        return team.getPrincipalTarget(role);
    }
    
    
//    public static void getTeamFromObject(String number) throws WTException{
//        WTDocument obj = DocUtil.getDocumentByNumber(number);
//        LOGGER.debug("DOC NAME:" + obj.getName());
//        QueryResult qr = WfEngineHelper.service.getAssociatedProcesses(
//                obj, WfState.OPEN_RUNNING, null);
//        if (qr != null && qr.size() > 0) {
//            Object a = qr.nextElement();
//            WfProcess processFrom = (WfProcess) a;
//            wt.team.Team teamFrom = (wt.team.Team) processFrom
//                    .getTeamId().getObject();
//            LOGGER.debug("TEAM NAME:" + teamFrom.getName());
//            Map roleMap = teamFrom.getRolePrincipalMap();
//            Set set = roleMap.keySet();
//            
//            LOGGER.debug("TEAM roleMap:" + roleMap.toString());
//            LOGGER.debug("TEAM SET:" + set.toString());
///*            
//
//            
//            
//            
//            Role role = Role.toRole("SW_TEMPLATE");
//            WTUser user = RoleUtil.getUserByName("kira");
//            teamFrom.addPrincipal(role, user);
//            user = RoleUtil.getUserByName("user02");
//            teamFrom.addPrincipal(role, user);
//            teamFrom = (Team) PersistenceHelper.manager.refresh(teamFrom);*/
//            roleMap = teamFrom.getRolePrincipalMap();
//            set = roleMap.keySet();
//            Iterator it = set.iterator();
//           while(it.hasNext()){
//               Role roleTmp = (Role) it.next();
//              List<WTPrincipalReference> list =  (List<WTPrincipalReference>) roleMap.get(roleTmp);
//              for(WTPrincipalReference pr:list){
//                  WTPrincipal wtp = pr.getPrincipal();
//                  if(wtp instanceof WTUser){
//                      WTUser userTmp = (WTUser) wtp;
//                      LOGGER.debug("用户：" + userTmp.getFullName());
//                      if(userTmp.getName().contains("Dimission"))
//                          {
//                              LOGGER.debug("角色：" + roleTmp.getStringValue()+ " 已移除用户：" + userTmp.getFullName());
//                              teamFrom.deletePrincipalTarget(roleTmp, userTmp);
//                          }
//                  }
//              }
//           } 
//           teamFrom = (Team) PersistenceHelper.manager.refresh(teamFrom);
//            LOGGER.debug("TEAM roleMap2:" + teamFrom.getRolePrincipalMap());
//            
//        }
//        
//        /**
//         * Test Folder.
//         */
//        Folder folder = FolderHelper.service.getFolder("/Default", obj.getContainerReference());
//        QueryResult qrf = FolderHelper.service.findSubFolders(folder);
//        while (qrf != null && qrf.hasMoreElements()) {
//            SubFolder childFolder = (SubFolder) qrf.nextElement();
//            LOGGER.debug("SUB FOLDER:" + childFolder.getName());
//        }
//        
//    }
    
    public static void accessControlHelper(){
//        AccessControlHelper.manager.createAccessControlRule(null, arg1, arg2, arg3, arg4, arg5);
    }
    
    
    public static void main(String[] args) throws ConfigException, WTException, MalformedURLException, RemoteException, InvocationTargetException {
        System.out.println("Running main method.");
        URL codebase_url = new URL("http://wncdev.x1929.com/Windchill/");
        RemoteMethodServer rms = RemoteMethodServer.getInstance(codebase_url);
        RemoteMethodServer remoteServer = RemoteMethodServer.getDefault();
        rms.setUserName("kira");
        rms.setPassword("1");
//        rms.getAuthenticator();
//        rms.invoke("getAllProducts", "com.x1929.wncdev.common.util.ContainerUtil", null, new Class[] {}, new Object[] { });
//        rms.invoke("getProductDomain", "com.x1929.wncdev.common.util.ContainerUtil", null, new Class[] {String.class}, new Object[] { "iPhone8"});
        //rms.invoke("getProductTeam", "com.x1929.wncdev.common.util.ContainerUtil", null, new Class[] {String.class}, new Object[] { "iPhone8"});
//        rms.invoke("getWindchillType", "com.x1929.wncdev.common.util.ContainerUtil", null, new Class[] {}, new Object[] {});
        //        rms.invoke("getAllState", "com.x1929.wncdev.common.util.ContainerUtil", null, new Class[] {}, new Object[] {});
          rms.invoke("getTeamFromObject", "com.x1929.wncdev.common.util.ContainerUtil", null, new Class[] {String.class}, new Object[] {"0000000950"});
        
          
          SuggestTextBox sug = new SuggestTextBox("","");
          //add comments 20191126-eclipse
          //add comments. 20191126-1
          //add comments 20191126-eclipse2
          //add comments. 20191126-2
          //add comments 20191126-eclipse3
          //add comments 20191126-eclipse4
          //add comments. 20191126-3

    }
    
}
 